﻿using Extentions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Web;
using TesseractOCR;
using TesseractOCR.Enums;
using TrainingReminderSystem.Model;

namespace TrainingReminderSystem.Bll.NetInterface
{
    /// <summary>
    /// 证书查询
    /// </summary>
    public static class CertSearchHelper
    {
        private static Engine _engine;

        /// <summary>
        /// 识别
        /// </summary>
        public static Engine Engine
        {
            get
            {
                if (_engine != null) return _engine;
                _engine = new Engine(@"./TesseractOCR", TesseractOCR.Enums.Language.English, EngineMode.Default);
                return _engine;
            }
        }

        public const string Base64Preff = "data:image/gif;base64,";

        /// <summary>
        /// 得到验证码
        /// </summary>
        /// <param name="saveFile"></param>
        /// <returns></returns>
        public static AjaxResult<UuidCode> GetCode(bool saveFile = false)
        {
            string url = "https://cx.mem.gov.cn/prod-api/certsearch/code";
            string content = null;
            try
            {
                content = Get(url, null, "utf-8", "application/json", headers: null, timeOut: 2000);
            }
            catch (Exception ex)
            {
                var errMsg = "请求Url失败:" + ex.Message;
                return AjaxResult<UuidCode>.ErrorResult(errMsg);
            }
            //{
            //    "msg": "操作成功",
            //    "img": "XXX",//img的src属性需要补前缀 data:image/gif;base64,
            //    "code": 200,
            //    "captchaOnOff": true,
            //    "uuid": "aaa1ba1ba8aa4e63a44f2ac6960662df"
            //}
            JObject? jObj = null;
            try
            {
                jObj = JsonHelper.DeserializeObject(content) as JObject;
                if (jObj == null) throw new Exception("转换失败");
            }
            catch (Exception ex)
            {
                string errMsg = $"转换Json失败:{ex.Message};原内容:" + content;
                return AjaxResult<UuidCode>.ErrorResult(errMsg);
            }
            bool succes = jObj["code"]?.ToString() == "200";
            if (succes == false)
            {
                string errMsg = $"请求内容失败,原内容:" + content;
                return AjaxResult<UuidCode>.ErrorResult(errMsg);
            }
            string? uuid = jObj["uuid"]?.ToString();
            string? base64 = jObj["img"]?.ToString();
            byte[] bytes = Convert.FromBase64String(base64);
            var img = TesseractOCR.Pix.Image.LoadFromMemory(bytes);
            using var page = Engine.Process(img);
            //Console.WriteLine("Mean confidence: {0}", page.MeanConfidence);
            //Console.WriteLine("Text: \r\n{0}", page.Text.Trim());
            string file = null;
            if (saveFile)
            {
                file = Base64Helper.SaveFileFromBase642(Base64Preff + base64, $"{page.Text.Trim()}_{page.MeanConfidence.ToString("0.00")}.gif", null);
            }
            //return $"请求结果:{page.MeanConfidence} {page.Text.Trim()}";
            var r = new UuidCode()
            {
                UUID = uuid,
                Code = page.Text.Trim(),
                CodeFileName = file,
            };
            return AjaxResult<UuidCode>.SuccessResult(r);
        }

        /// <summary>
        /// 验证码
        /// </summary>
        public class UuidCode
        {
            public string UUID { get; set; }

            public string Code { get; set; }

            public string CodeFileName { get; set; }
        }

        /// <summary>
        /// 得到信息
        /// </summary>
        /// <param name="name">姓名</param>
        /// <param name="idcardNum">证件号</param>
        /// <param name="uuidCode"></param>
        /// <param name="idcardTypeCode">
        /// {
        ///     value: "01",
        ///     label: "身份证"
        /// }, {
        ///     value: "02",
        ///     label: "军官证"
        /// }, {
        ///     value: "03",
        ///     label: "护照"
        /// }, {
        ///     value: "04",
        ///     label: "其他"
        /// }</param>
        /// <param name="last">personTypeCode=03特种作业操作证查询 personTypeCode=02安全生产知识和管理能力考核合格信息查询</param>
        /// <returns></returns>
        private static AjaxResult<string> GetBaseInfo(string name, string idcardNum, UuidCode uuidCode, string idcardTypeCode = "01", string last = "personTypeCode=03")
        {
            string url = $"https://cx.mem.gov.cn/prod-api/certsearch/certInfo/netQuery?name={HttpUtility.UrlEncode(name)}&searchType=1&idcardNum={idcardNum}&idcardTypeCode=01&code={uuidCode.Code}&uuid={uuidCode.UUID}" + (!string.IsNullOrEmpty(last) ? "&" + last : string.Empty);
            string content = null;
            try
            {
                content = Get(url, null, "utf-8", "application/json", headers: null, timeOut: 2000);
            }
            catch (Exception ex)
            {
                var errMsg = "请求Url失败:" + ex.Message;
                return AjaxResult<string>.ErrorResult(errMsg);
            }
            //{ "msg":"验证码错误","code":500}
            //{ "msg":"操作成功","code":200,"data":[]}
            JObject? jObj = null;
            try
            {
                jObj = JsonHelper.DeserializeObject(content) as JObject;
                if (jObj == null) throw new Exception("转换失败");
            }
            catch (Exception ex)
            {
                string errMsg = $"转换Json失败:{ex.Message};原内容:" + content;
                return AjaxResult<string>.ErrorResult(errMsg);
            }
            bool succes = jObj["code"]?.ToString() == "200";
            if (succes == false)
            {
                string errMsg = $"请求内容失败,原内容:" + content;
                return AjaxResult<string>.ErrorResult(errMsg);
            }
            string? data = jObj["data"]?.ToString();
            return AjaxResult<string>.SuccessResult(data);
        }

        /// <summary>
        /// 得到信息
        /// </summary>
        /// <param name="name">姓名</param>
        /// <param name="idcardNum">证件号</param>
        /// <param name="idcardTypeCode">
        /// {
        ///     value: "01",
        ///     label: "身份证"
        /// }, {
        ///     value: "02",
        ///     label: "军官证"
        /// }, {
        ///     value: "03",
        ///     label: "护照"
        /// }, {
        ///     value: "04",
        ///     label: "其他"
        /// }</param>
        /// <param name="last">personTypeCode=03特种作业操作证查询 personTypeCode=02安全生产知识和管理能力考核合格信息查询</param>
        /// <returns></returns>
        public static AjaxResult<string> GetInfo(string name, string idcardNum, string idcardTypeCode = "01", string last = "personTypeCode=03")
        {
            var r = GetCode(false);
            if (r.Success == false)
            {
                return AjaxResult<string>.ErrorResult(r.Message);
            }
            var uuidCode = r.Result;
            return GetBaseInfo(name, idcardNum, uuidCode, idcardTypeCode, last);
        }

        #region 网络请求

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="data"></param>
        /// <param name="strEncoding"></param>
        /// <param name="contentType"></param>
        /// <param name="headers"></param>
        /// <param name="timeOut"></param>
        /// <returns></returns>
        private static string Get(string url, string data = null, string strEncoding = "utf-8", string contentType = "application/x-www-form-urlencoded", Dictionary<string, string> headers = null, int timeOut = 3000)
        {
            return Request(url, data, strEncoding, contentType, headers, timeOut, HttpMethod.Get);
        }

        private static string Request(string url, string data = null, string strEncoding = "utf-8", string contentType = "application/x-www-form-urlencoded", Dictionary<string, string> headers = null, int timeOut = 3000, HttpMethod httpMethod = null)
        {
            if (httpMethod == null) { httpMethod = HttpMethod.Post; }
            HttpClient client = null;
            if (SysConfig.ProxyEnable == false)
            {
                client = HttpWebRequestHelper.CreateHttpClient();
            }
            else
            {
                // 创建 HttpClientHandler 实例
                HttpClientHandler handler = new HttpClientHandler();
                handler.UseProxy = true;
                // 配置代理服务器
                string proxyUrl = $"http://{SysConfig.ProxyIP}:{SysConfig.ProxyPort}";
                handler.Proxy = new System.Net.WebProxy(proxyUrl, false);
                // 添加这行认证信息
                handler.Proxy.Credentials = new NetworkCredential(SysConfig.ProxyUID, SysConfig.ProxyPwd);
                // 禁用证书吊销检查
                handler.CheckCertificateRevocationList = false;
                // 自定义证书验证回调
                handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
                {
                    // 这里可以添加自定义验证逻辑
                    return true; // 接受所有证书（仅测试环境）
                };
                client = new HttpClient(handler);
            }
            using (client)
            {
                client.Timeout = TimeSpan.FromMilliseconds(timeOut);
                client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,*/*");
                if (headers != null && headers.Count > 0)
                {
                    foreach (var item in headers)
                    {
                        client.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue() { NoStore = true };
                using HttpRequestMessage request = new HttpRequestMessage(httpMethod, url);
                var encoding = Encoding.GetEncoding(strEncoding);
                if (data != null)
                {
                    request.Content = new StringContent(data, encoding, contentType);
                }
                using HttpResponseMessage response = client.Send(request);
                response.EnsureSuccessStatusCode();
                using StreamReader reader = new StreamReader(response.Content.ReadAsStream(), encoding);
                string responseCount = reader.ReadToEnd();
                return responseCount;
            }
        }

        #endregion
    }
}
